/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.os;

import android.util.ArrayMap;
import android.util.Log;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;

/**
 * 从字符串值到各种类型的映射。
 */
public class BaseBundle {
    private static final String TAG = "Bundle";
    static final boolean DEBUG = false;

    static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L'
    static final Parcel EMPTY_PARCEL;

    static {
        EMPTY_PARCEL = Parcel.obtain();
    }

    // 不变量——mMap / mParcelledData中只有一个是null(除了调用unparcel外)

    ArrayMap<String, Object> mMap = null;

    /*
     *如果mParcelledData是非空的，那么mMap将为null，数据存储为包含一个包的包。当数据未被分配时，mParcelledData将被设置为null。
     */
    Parcel mParcelledData = null;

    /**
     *当从mParcelledData中解包数据时使用的类加载器。
     */
    private ClassLoader mClassLoader;

    /**
     * 构建一个新的、空的Bundle，它使用特定的类加载器来实例化Parcelable和Serializable对象。
     *
     * @param loader 在实例化对象时使用的显式类加载器。
     * inside of the Bundle.
     * @param capacity Initial size of the ArrayMap.
     */
    BaseBundle(ClassLoader loader, int capacity) {
        mMap = capacity > 0 ?
                new ArrayMap<String, Object>(capacity) : new ArrayMap<String, Object>();
        mClassLoader = loader == null ? getClass().getClassLoader() : loader;
    }

    /**
     *构建一个新的空包。
     */
    BaseBundle() {
        this((ClassLoader) null, 0);
    }

    /**
     * 构造一个包，其数据存储为一个包。数据将在第一次接触时被分配，使用指定的类加载器。
     *
     * @param parcelledData a Parcel containing a Bundle
     */
    BaseBundle(Parcel parcelledData) {
        readFromParcelInner(parcelledData);
    }

    BaseBundle(Parcel parcelledData, int length) {
        readFromParcelInner(parcelledData, length);
    }

    /**
     * 构建一个新的、空的Bundle，它使用特定的类加载器来实例化Parcelable和Serializable对象。
     *
     * @param loader An explicit ClassLoader to use when instantiating objects
     * inside of the Bundle.
     */
    BaseBundle(ClassLoader loader) {
        this(loader, 0);
    }

    /**
     * 构造一个新的空包大小给定的元素数量。包将会增长。
     *
     * @param capacity the initial capacity of the Bundle
     */
    BaseBundle(int capacity) {
        this((ClassLoader) null, capacity);
    }

    /**
     * 构造一个包，其中包含来自给定包的映射的副本。
     *
     * @param b a Bundle to be copied.
     */
    BaseBundle(BaseBundle b) {
        if (b.mParcelledData != null) {
            if (b.mParcelledData == EMPTY_PARCEL) {
                mParcelledData = EMPTY_PARCEL;
            } else {
                mParcelledData = Parcel.obtain();
                mParcelledData.appendFrom(b.mParcelledData, 0, b.mParcelledData.dataSize());
                mParcelledData.setDataPosition(0);
            }
        } else {
            mParcelledData = null;
        }

        if (b.mMap != null) {
            mMap = new ArrayMap<String, Object>(b.mMap);
        } else {
            mMap = null;
        }

        mClassLoader = b.mClassLoader;
    }

    /**
     * TODO: 优化后(获得的价值一双包与单个的一部分)一旦Bundle.forPair()实现以上特别单一映射实现/序列化。
     *
     * Note: 单对包中的值可能为null。
     *
     * @hide
     */
    public String getPairValue() {
        unparcel();
        int size = mMap.size();
        if (size > 1) {
            Log.w(TAG, "getPairValue() used on Bundle with multiple pairs.");
        }
        if (size == 0) {
            return null;
        }
        Object o = mMap.valueAt(0);
        try {
            return (String) o;
        } catch (ClassCastException e) {
            typeWarning("getPairValue()", o, "String", e);
            return null;
        }
    }

    /**
     * 在实例化对象时更改这个Bundle使用的类加载器。
     *
     * @param loader 一个显式的类加载器，用于在包的内部实例化对象。
     */
    void setClassLoader(ClassLoader loader) {
        mClassLoader = loader;
    }

    /**
     *返回当前与该包关联的类加载器。
     */
    ClassLoader getClassLoader() {
        return mClassLoader;
    }

    /**
     * 如果底层数据存储为一个包，则使用当前指定的类装入器将其解包。
     */
    /* package */ synchronized void unparcel() {
        if (mParcelledData == null) {
            if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
                    + ": no parcelled data");
            return;
        }

        if (mParcelledData == EMPTY_PARCEL) {
            if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
                    + ": empty");
            if (mMap == null) {
                mMap = new ArrayMap<String, Object>(1);
            } else {
                mMap.erase();
            }
            mParcelledData = null;
            return;
        }

        int N = mParcelledData.readInt();
        if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
                + ": reading " + N + " maps");
        if (N < 0) {
            return;
        }
        if (mMap == null) {
            mMap = new ArrayMap<String, Object>(N);
        } else {
            mMap.erase();
            mMap.ensureCapacity(N);
        }
        mParcelledData.readArrayMapInternal(mMap, N, mClassLoader);
        mParcelledData.recycle();
        mParcelledData = null;
        if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
                + " final map: " + mMap);
    }

    /**
     * @hide
     */
    public boolean isParcelled() {
        return mParcelledData != null;
    }

    /**
     * 返回此包中包含的映射数。
     *
     * @return the number of mappings as an int.
     */
    public int size() {
        unparcel();
        return mMap.size();
    }

    /**
     * 如果此包的映射为空，则返回true，否则为false。
     */
    public boolean isEmpty() {
        unparcel();
        return mMap.isEmpty();
    }

    /**
     * 从这个包的映射中删除所有元素。
     */
    public void clear() {
        unparcel();
        mMap.clear();
    }

    /**
     *如果给定的键包含在这个包的映射中，则返回true。
     *
     * @param key a String key
     * @return true if the key is part of the mapping, false otherwise
     */
    public boolean containsKey(String key) {
        unparcel();
        return mMap.containsKey(key);
    }

    /**
     *以给定键作为对象返回条目。
     *
     * @param key a String key
     * @return an Object, or null
     */
    public Object get(String key) {
        unparcel();
        return mMap.get(key);
    }

    /**
     *从这个包的映射中删除给定键的任何条目。
     *
     * @param key a String key
     */
    public void remove(String key) {
        unparcel();
        mMap.remove(key);
    }

    /**
     * 将来自给定持久化包的所有映射插入到这个BaseBundle中。
     *
     * @param bundle a PersistableBundle
     */
    public void putAll(PersistableBundle bundle) {
        unparcel();
        bundle.unparcel();
        mMap.putAll(bundle.mMap);
    }

    /**
     *将所有映射从给定映射插入到这个基包中。
     *
     * @param map a Map
     */
    void putAll(Map map) {
        unparcel();
        mMap.putAll(map);
    }

    /**
     * 返回一个集合，其中包含用作这个包中的键的字符串。
     *
     * @return a Set of String keys
     */
    public Set<String> keySet() {
        unparcel();
        return mMap.keySet();
    }

    /**
     * 将布尔值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value a Boolean, or null
     */
    void putBoolean(String key, boolean value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     *将字节值插入到这个包的映射中，替换给定键的任何现有值。
     *
     * @param key a String, or null
     * @param value a byte
     */
    void putByte(String key, byte value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 将char值插入到这个包的映射中，替换给定键的任何现有值。
     *
     * @param key a String, or null
     * @param value a char, or null
     */
    void putChar(String key, char value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 将一个短值插入到这个包的映射中，替换给定键的任何现有值。
     *
     * @param key a String, or null
     * @param value a short
     */
    void putShort(String key, short value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 将int值插入到这个包的映射中，替换给定键的任何现有值。
     *
     * @param key a String, or null
     * @param value an int, or null
     */
    public void putInt(String key, int value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     *将一个长值插入到这个包的映射中，替换给定键的任何现有值。
     *
     * @param key a String, or null
     * @param value a long
     */
    public void putLong(String key, long value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 将浮点值插入到这个包的映射中，替换给定ke的任何现有值。y.
     *
     * @param key a String, or null
     * @param value a float
     */
    void putFloat(String key, float value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 将一个双值插入到这个包的映射中，替换给定键的任何现有值。
     *
     * @param key a String, or null
     * @param value a double
     */
    public void putDouble(String key, double value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 将字符串值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value a String, or null
     */
    public void putString(String key, String value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 将CharSequence值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value a CharSequence, or null
     */
    void putCharSequence(String key, CharSequence value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     *将ArrayList<Integer>值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value an ArrayList<Integer> object, or null
     */
    void putIntegerArrayList(String key, ArrayList<Integer> value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     *在这个包的映射中插入一个ArrayList<String>值，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value an ArrayList<String> object, or null
     */
    void putStringArrayList(String key, ArrayList<String> value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 将ArrayList<CharSequence>值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value an ArrayList<CharSequence> object, or null
     */
    void putCharSequenceArrayList(String key, ArrayList<CharSequence> value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 将可序列化的值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value a Serializable object, or null
     */
    void putSerializable(String key, Serializable value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 将布尔数组值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value a boolean array object, or null
     */
    void putBooleanArray(String key, boolean[] value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 将字节数组值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value a byte array object, or null
     */
    void putByteArray(String key, byte[] value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     *将一个短数组值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value a short array object, or null
     */
    void putShortArray(String key, short[] value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 将char数组值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value a char array object, or null
     */
    void putCharArray(String key, char[] value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     *将int数组值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value an int array object, or null
     */
    public void putIntArray(String key, int[] value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     *将一个长数组值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value a long array object, or null
     */
    public void putLongArray(String key, long[] value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 将浮点数组值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value a float array object, or null
     */
    void putFloatArray(String key, float[] value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 将一个双数组值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value a double array object, or null
     */
    public void putDoubleArray(String key, double[] value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 将字符串数组值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value a String array object, or null
     */
    public void putStringArray(String key, String[] value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     *将CharSequence数组值插入到这个包的映射中，替换给定键的任何现有值。键或值都可以为空。
     *
     * @param key a String, or null
     * @param value a CharSequence array object, or null
     */
    void putCharSequenceArray(String key, CharSequence[] value) {
        unparcel();
        mMap.put(key, value);
    }

    /**
     * 返回与给定键关联的值，如果给定键不存在所需类型的映射，则返回false。
     *
     * @param key a String
     * @return a boolean value
     */
    boolean getBoolean(String key) {
        unparcel();
        if (DEBUG) Log.d(TAG, "Getting boolean in "
                + Integer.toHexString(System.identityHashCode(this)));
        return getBoolean(key, false);
    }

    // Log a message if the value was non-null but not of the expected type
    void typeWarning(String key, Object value, String className,
            Object defaultValue, ClassCastException e) {
        StringBuilder sb = new StringBuilder();
        sb.append("Key ");
        sb.append(key);
        sb.append(" expected ");
        sb.append(className);
        sb.append(" but value was a ");
        sb.append(value.getClass().getName());
        sb.append(".  The default value ");
        sb.append(defaultValue);
        sb.append(" was returned.");
        Log.w(TAG, sb.toString());
        Log.w(TAG, "Attempt to cast generated internal exception:", e);
    }

    void typeWarning(String key, Object value, String className,
            ClassCastException e) {
        typeWarning(key, value, className, "<null>", e);
    }

    /**
     * 返回与给定键关联的值，如果给定的键不存在所需类型的映射，则返回defaultValue。
     *
     * @param key a String
     * @param defaultValue Value to return if key does not exist
     * @return a boolean value
     */
    boolean getBoolean(String key, boolean defaultValue) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return defaultValue;
        }
        try {
            return (Boolean) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "Boolean", defaultValue, e);
            return defaultValue;
        }
    }

    /**
     *返回与给定键关联的值，或(字节)0，如果给定键不存在所需类型的映射。
     *
     * @param key a String
     * @return a byte value
     */
    byte getByte(String key) {
        unparcel();
        return getByte(key, (byte) 0);
    }

    /**
     * 返回与给定键关联的值，如果给定的键不存在所需类型的映射，则返回defaultValue。
     *
     * @param key a String
     * @param defaultValue Value to return if key does not exist
     * @return a byte value
     */
    Byte getByte(String key, byte defaultValue) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return defaultValue;
        }
        try {
            return (Byte) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "Byte", defaultValue, e);
            return defaultValue;
        }
    }

    /**
     * 返回与给定键关联的值，或者(char) 0，如果给定的键不存在所需类型的映射。
     *
     * @param key a String
     * @return a char value
     */
    char getChar(String key) {
        unparcel();
        return getChar(key, (char) 0);
    }

    /**
     * 返回与给定键关联的值，如果给定的键不存在所需类型的映射，则返回defaultValue。
     *
     * @param key a String
     * @param defaultValue Value to return if key does not exist
     * @return a char value
     */
    char getChar(String key, char defaultValue) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return defaultValue;
        }
        try {
            return (Character) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "Character", defaultValue, e);
            return defaultValue;
        }
    }

    /**
     * 返回与给定键关联的值，或(short) 0，如果给定键不存在所需类型的映射。
     *
     * @param key a String
     * @return a short value
     */
    short getShort(String key) {
        unparcel();
        return getShort(key, (short) 0);
    }

    /**
     *返回与给定键关联的值，如果给定的键不存在所需类型的映射，则返回defaultValue。
     *
     * @param key a String
     * @param defaultValue Value to return if key does not exist
     * @return a short value
     */
    short getShort(String key, short defaultValue) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return defaultValue;
        }
        try {
            return (Short) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "Short", defaultValue, e);
            return defaultValue;
        }
    }

    /**
     * 返回与给定键关联的值，如果给定键不存在所需类型的映射，则返回0。
     *
     * @param key a String
     * @return an int value
     */
    public int getInt(String key) {
        unparcel();
        return getInt(key, 0);
    }

    /**
     *返回与给定键关联的值，如果给定的键不存在所需类型的映射，则返回defaultValue。
     *
     * @param key a String
     * @param defaultValue Value to return if key does not exist
     * @return an int value
     */
   public int getInt(String key, int defaultValue) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return defaultValue;
        }
        try {
            return (Integer) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "Integer", defaultValue, e);
            return defaultValue;
        }
    }

    /**
     * 返回与给定键关联的值，如果给定键不存在所需类型的映射，则返回0L。
     *
     * @param key a String
     * @return a long value
     */
    public long getLong(String key) {
        unparcel();
        return getLong(key, 0L);
    }

    /**
     * 返回与给定键关联的值，如果给定的键不存在所需类型的映射，则返回defaultValue。
     *
     * @param key a String
     * @param defaultValue Value to return if key does not exist
     * @return a long value
     */
    public long getLong(String key, long defaultValue) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return defaultValue;
        }
        try {
            return (Long) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "Long", defaultValue, e);
            return defaultValue;
        }
    }

    /**
     * 返回与给定键关联的值，如果给定键不存在所需类型的映射，则返回0.0f。
     *
     * @param key a String
     * @return a float value
     */
    float getFloat(String key) {
        unparcel();
        return getFloat(key, 0.0f);
    }

    /**
     * 返回与给定键关联的值，如果给定的键不存在所需类型的映射，则返回defaultValue。
     *
     * @param key a String
     * @param defaultValue Value to return if key does not exist
     * @return a float value
     */
    float getFloat(String key, float defaultValue) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return defaultValue;
        }
        try {
            return (Float) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "Float", defaultValue, e);
            return defaultValue;
        }
    }

    /**
     * 返回与给定键关联的值，如果给定键不存在所需类型的映射，则返回0.0。
     *
     * @param key a String
     * @return a double value
     */
    public double getDouble(String key) {
        unparcel();
        return getDouble(key, 0.0);
    }

    /**
     * 返回与给定键关联的值，如果给定的键不存在所需类型的映射，则返回defaultValue。
     *
     * @param key a String
     * @param defaultValue Value to return if key does not exist
     * @return a double value
     */
    public double getDouble(String key, double defaultValue) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return defaultValue;
        }
        try {
            return (Double) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "Double", defaultValue, e);
            return defaultValue;
        }
    }

    /**
     * 返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值。
     *
     * @param key a String, or null
     * @return a String value, or null
     */
    public String getString(String key) {
        unparcel();
        final Object o = mMap.get(key);
        try {
            return (String) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "String", e);
            return null;
        }
    }

    /**
     * 返回与给定键关联的值，如果给定键不存在所需类型的映射，或者null值与给定键显式关联，则返回defaultValue。
     *
     * @param key a String, or null
     * @param defaultValue Value to return if key does not exist or if a null
     *     value is associated with the given key.
     * @return the String value associated with the given key, or defaultValue
     *     if no valid String object is currently mapped to that key.
     */
    public String getString(String key, String defaultValue) {
        final String s = getString(key);
        return (s == null) ? defaultValue : s;
    }

    /**
     *返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值。
     *
     * @param key a String, or null
     * @return a CharSequence value, or null
     */
    CharSequence getCharSequence(String key) {
        unparcel();
        final Object o = mMap.get(key);
        try {
            return (CharSequence) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "CharSequence", e);
            return null;
        }
    }

    /**
     *返回与给定键关联的值，如果给定键不存在所需类型的映射，或者null值与给定键显式关联，则返回defaultValue。
     *
     * @param key a String, or null
     * @param defaultValue Value to return if key does not exist or if a null
     *     value is associated with the given key.
     * @return the CharSequence value associated with the given key, or defaultValue
     *     if no valid CharSequence object is currently mapped to that key.
     */
    CharSequence getCharSequence(String key, CharSequence defaultValue) {
        final CharSequence cs = getCharSequence(key);
        return (cs == null) ? defaultValue : cs;
    }

    /**
     * 返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值。
     *
     * @param key a String, or null
     * @return a Serializable value, or null
     */
    Serializable getSerializable(String key) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (Serializable) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "Serializable", e);
            return null;
        }
    }

    /**
     * 返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值。
     *
     * @param key a String, or null
     * @return an ArrayList<String> value, or null
     */
    ArrayList<Integer> getIntegerArrayList(String key) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (ArrayList<Integer>) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "ArrayList<Integer>", e);
            return null;
        }
    }

    /**
     * 返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值
     *
     * @param key a String, or null
     * @return an ArrayList<String> value, or null
     */
    ArrayList<String> getStringArrayList(String key) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (ArrayList<String>) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "ArrayList<String>", e);
            return null;
        }
    }

    /**
     * 返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值。
     *
     * @param key a String, or null
     * @return an ArrayList<CharSequence> value, or null
     */
    ArrayList<CharSequence> getCharSequenceArrayList(String key) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (ArrayList<CharSequence>) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "ArrayList<CharSequence>", e);
            return null;
        }
    }

    /**
     * 返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值。
     *
     * @param key a String, or null
     * @return a boolean[] value, or null
     */
    boolean[] getBooleanArray(String key) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (boolean[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "byte[]", e);
            return null;
        }
    }

    /**
     * 返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值。
     *
     * @param key a String, or null
     * @return a byte[] value, or null
     */
    byte[] getByteArray(String key) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (byte[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "byte[]", e);
            return null;
        }
    }

    /**
     * 返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值。
     *
     * @param key a String, or null
     * @return a short[] value, or null
     */
    short[] getShortArray(String key) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (short[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "short[]", e);
            return null;
        }
    }

    /**
     * 返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值
     *
     * @param key a String, or null
     * @return a char[] value, or null
     */
    char[] getCharArray(String key) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (char[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "char[]", e);
            return null;
        }
    }

    /**
     * 返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值。
     *
     * @param key a String, or null
     * @return an int[] value, or null
     */
    public int[] getIntArray(String key) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (int[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "int[]", e);
            return null;
        }
    }

    /**
     * 返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值。
     *
     * @param key a String, or null
     * @return a long[] value, or null
     */
    public long[] getLongArray(String key) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (long[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "long[]", e);
            return null;
        }
    }

    /**
     * 返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值。
     *
     * @param key a String, or null
     * @return a float[] value, or null
     */
    float[] getFloatArray(String key) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (float[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "float[]", e);
            return null;
        }
    }

    /**
     * 返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值。
     *
     * @param key a String, or null
     * @return a double[] value, or null
     */
    public double[] getDoubleArray(String key) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (double[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "double[]", e);
            return null;
        }
    }

    /**
     *返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值。
     *
     * @param key a String, or null
     * @return a String[] value, or null
     */
    public String[] getStringArray(String key) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (String[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "String[]", e);
            return null;
        }
    }

    /**
     *返回与给定键相关联的值，如果给定键或null值不存在所需类型的映射，则返回与该键显式关联的值。
     *
     * @param key a String, or null
     * @return a CharSequence[] value, or null
     */
    CharSequence[] getCharSequenceArray(String key) {
        unparcel();
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (CharSequence[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "CharSequence[]", e);
            return null;
        }
    }

    /**
     * 将包内容写到一个包中，通常是为了让它通过IBinder连接。
     * @param parcel The parcel to copy this bundle to.
     */
    void writeToParcelInner(Parcel parcel, int flags) {
        if (mParcelledData != null) {
            if (mParcelledData == EMPTY_PARCEL) {
                parcel.writeInt(0);
            } else {
                int length = mParcelledData.dataSize();
                parcel.writeInt(length);
                parcel.writeInt(BUNDLE_MAGIC);
                parcel.appendFrom(mParcelledData, 0, length);
            }
        } else {
            // Special case for empty bundles.
            if (mMap == null || mMap.size() <= 0) {
                parcel.writeInt(0);
                return;
            }
            int lengthPos = parcel.dataPosition();
            parcel.writeInt(-1); // dummy, will hold length
            parcel.writeInt(BUNDLE_MAGIC);

            int startPos = parcel.dataPosition();
            parcel.writeArrayMapInternal(mMap);
            int endPos = parcel.dataPosition();

            // Backpatch length
            parcel.setDataPosition(lengthPos);
            int length = endPos - startPos;
            parcel.writeInt(length);
            parcel.setDataPosition(endPos);
        }
    }

    /**
     * 将包内容读入这个包，通常是为了让它通过IBinder连接。
     * @param parcel The parcel to overwrite this bundle from.
     */
    void readFromParcelInner(Parcel parcel) {
        int length = parcel.readInt();
        if (length < 0) {
            throw new RuntimeException("Bad length in parcel: " + length);
        }
        readFromParcelInner(parcel, length);
    }

    private void readFromParcelInner(Parcel parcel, int length) {
        if (length == 0) {
            // Empty Bundle or end of data.
            mParcelledData = EMPTY_PARCEL;
            return;
        }
        int magic = parcel.readInt();
        if (magic != BUNDLE_MAGIC) {
            //noinspection ThrowableInstanceNeverThrown
            throw new IllegalStateException("Bad magic number for Bundle: 0x"
                    + Integer.toHexString(magic));
        }

        // Advance within this Parcel
        int offset = parcel.dataPosition();
        parcel.setDataPosition(offset + length);

        Parcel p = Parcel.obtain();
        p.setDataPosition(0);
        p.appendFrom(parcel, offset, length);
        if (DEBUG) Log.d(TAG, "Retrieving "  + Integer.toHexString(System.identityHashCode(this))
                + ": " + length + " bundle bytes starting at " + offset);
        p.setDataPosition(0);

        mParcelledData = p;
    }
}
